﻿using UnityEngine;
using System.Collections;
using LitJson;
using System.Collections.Generic;
using System;
using SongeNS;
using FairyGUI.UI;
using System.IO;
using System.Text;

/// <summary>建筑信息与照片绑定编辑 的业务代码</summary>
public class BuildInfoEditor
{
    /// <summary> 获取走向图的前缀, 和商铺区分 </summary>
    public const string PreRouteBuildInfoEditor = "zpp";

    #region 单例

    static BuildInfoEditor instance;
    public static BuildInfoEditor Instance
    {
        get
        {
            if (instance == null)
                instance = new BuildInfoEditor();
            return instance;
        }
    }

    #endregion
    /// <summary>当前(最后)加载走向图的 建筑ID-建筑信息字典</summary>
    Dictionary<string, BuildInfo> curLoadedRouteDicBuildID2Info;
    /// <summary> 走向图 2 图片</summary>
    Dictionary<string, List<PicVO>> dicRoutID2Pics = new Dictionary<string, List<PicVO>>();
    /// <summary>走向图ID 2 该走向图下的建筑ID-建筑信息字典 </summary>
    Dictionary<string, Dictionary<string, BuildInfo>> dicRoutID2Buildinfos = new Dictionary<string, Dictionary<string, BuildInfo>>();
    public JsonData JDConfig { get; set; }
    bool _isShowingPhotoEditorEditedColor = false;

    string _curShowingRouteID = "";
    BuildInfo lastSaveBuildInfo;

    public const string STR_NO_BUILDING_SELECT = "没有选择建筑";
    void LoadConfig()
    {
        if (JDConfig != null)
        {
            return;
        }

        string url = Application.streamingAssetsPath + "/NewEditorConfig.txt";
        if (File.Exists(url))
        {
            JDConfig = JsonMapper.ToObject(File.ReadAllText(url));
        }
        else
        {
            Debug.Log("获取配置文件NewEditorConfig失败");
        }
    }

    public List<string> GetBuildTypeList()
    {
        if (null == JDConfig)
        {
            LoadConfig();
            if (null == JDConfig)
            {
                return new List<string>();
            }
        }

        var jdBuildType = JDConfig["configs"].ReadJsonData("buildType");
        if (jdBuildType != null)
        {
            return jdBuildType.ToStringList();
        }
        return new List<string>();
    }


    #region 选中管理
    SceneNodeMono curSelect;
    SceneNodeMono lastSelect;
    public SceneNodeMono CurSelect
    {
        get
        {
            return curSelect;
        }

        set
        {
            if (CurSelect != value)
            {
                lastSelect = curSelect;
                curSelect = value;
                _OnCurentSelectChanged();
            }
        }
    }


    #endregion

    #region 事件管理

    public void OnMouseEvent(MouseEvent me)
    {
        switch (me.eventType)
        {
            case MouseEvent.MouseDown:
                {
                    // 左键
                    if (me.mouse == 0)
                    {
                        CurSelect = me.tar as SceneNodeMono;
                    }
                }
                break;
        }
    }

    public void _OnCurentSelectChanged()
    {
        BuildInfo buildInfo = null;
        if (curSelect != null)
        {
            EventManager.instance.DispatchEvent(null, UICONST.BIE_CHANGE_CURRENT_SELECTION, curSelect.gameObject);

            //SceneManager.Instance.DrawModelWire(curSelect.gameObject);
            SceneManager.Instance.DrawMeshWire(CurSelect.gameObject);

            var node = curSelect.sceneNode;
            buildInfo = GetBuildInfo(node.picRouteID, node.guid);
            if (null == buildInfo)
            {
                buildInfo = new BuildInfo();
                buildInfo.isTemp = true;
                buildInfo.picRouteID = node.picRouteID;
                if ("null" == buildInfo.picRouteID || null == buildInfo.picRouteID)
                {
                    buildInfo.picRouteID = "需要设置走向图ID或绑定走向图图片";
                }
                else
                {
                    buildInfo.buildType = "需加载走向图数据";
                }
            }
        }
        else
        {
            //SceneManager.Instance.DontDrawMeshWire();
            EventManager.instance.DispatchEvent(null, UICONST.BIE_CHANGE_CURRENT_SELECTION, null);
            SceneManager.Instance.ClearDraw();
        }

        if (null == buildInfo)
        {
            buildInfo = new BuildInfo();
            buildInfo.isTemp = true;
            buildInfo.picRouteID = STR_NO_BUILDING_SELECT;
        }

        string lastRouteID = _curShowingRouteID;
        EventManager.instance.DispatchEvent(null, UICONST.BIE_UPDATE_SELECTION, buildInfo);
        string curRouteID = _curShowingRouteID;

        string curGUI = (CurSelect == null) ? "" : CurSelect.sceneNode.guid;
        RefreshEditedBuildingsColorSwitch(lastRouteID, curRouteID, curGUI);
    }

    public BuildInfo GetCurSelectBuildInfo()
    {
        if (CurSelect != null)
        {
            var node = CurSelect.sceneNode;
            if (node != null)
            {
                return GetBuildInfo(node.picRouteID, node.guid);
            }
        }
        return null;
    }

    public BuildInfo GetBuildInfo(string routeID, string guid)
    {
        if (!string.IsNullOrEmpty(routeID))
        {
            var dic = dicRoutID2Buildinfos.TryGetReturnValue(routeID);
            if (dic != null)
            {
                 return dic.TryGetReturnValue(guid);
            }
        }
        return null;
    }

    WindowAlertDialog _hintWindow;
    WindowAlertDialog HintWindow
    {
        get
        {
            if (_hintWindow != null)
            {
                return _hintWindow;
            }
            _hintWindow = new WindowAlertDialog("");
            return _hintWindow;
        }
    }

    public Dictionary<string, BuildInfo> GetCurBuildInfoDict()
    {
        return dicRoutID2Buildinfos.TryGetReturnValue(_curShowingRouteID);
    }

    public bool GetIsShowingPhotoEditorEditedColor()
    {
        return _isShowingPhotoEditorEditedColor;
    }

    void SetIsShowingPhotoEditorEditedColor(bool value)
    {
        bool flag = false;
        if (_isShowingPhotoEditorEditedColor != value)
        {
            flag = true;
        }
        _isShowingPhotoEditorEditedColor = value;

        if (flag)
        {
            InnerRefreshCurEditedBuildingsColor();
        }
    }

    BuildInfo GetLastSaveBuildInfo()
    {
        return lastSaveBuildInfo;             
    }

    void OnSaveBuildInfo(BuildInfo bi)
    {
        if (CurSelect != null)
        {
            var dicBuildInfo = dicRoutID2Buildinfos.TryGetReturnValue(bi.picRouteID);
            if (dicBuildInfo != null)
            {
                bi.isTemp = false;
                dicBuildInfo.AddOrReplace(curSelect.sceneNode.guid, bi);
                CurSelect.sceneNode.picRouteID = bi.picRouteID;

                InnerRefreshCurEditedBuildingsColor(curSelect.sceneNode.guid);

                lastSaveBuildInfo = bi;
                EventManager.instance.DispatchEvent(null, UICONST.BIE_RET_GET_LAST_SAVE_BUILDINFO, GetLastSaveBuildInfo());
                EventManager.instance.DispatchEvent(null, UICONST.BIE_SHOW_INFO, "保存信息到本地成功, 配置完成后请保存到云端");
            }
            else
            {
                if (string.IsNullOrEmpty(CurSelect.sceneNode.picRouteID) || CurSelect.sceneNode.picRouteID == "null")
                {
                    ShowHint("该建筑没有设置走向图ID, 需要绑定走向图图片后才能保存\n(DebugInfo :" +
                        "保存" + curSelect + "失败," + "RouteID为" + bi.picRouteID + "GUID为" + CurSelect.sceneNode.guid + ")");
                }
                else
                {                    
                    ShowHint("请先加载走向图数据, 配置后再保存\n(DebugInfo :" +
                        "保存" + curSelect + "失败," + "RouteID为" + bi.picRouteID + "GUID为" + CurSelect.sceneNode.guid + ")");
                }
            }
        }
        else
        {            
            ShowHint("请先选择建筑, 配置后再保存");
        }
    }

    void ShowHint(string str)
    {
        HintWindow.Show();
        HintWindow.SetInformation(str);
    }

    void UpToServer()
    {
        //UploadBuildInfoData();
        CompEditor.Instance.SaveData(SceneManager.Instance.ToJson(), UploadBuildInfoData, false);
    }

    StringBuilder sb = new StringBuilder();
    void UploadBuildInfoData()
    {
        // 只上传就好. 本地使用的就是临时数据
        var it = dicRoutID2Buildinfos.GetEnumerator();
        if (dicRoutID2Buildinfos.Count == 0)
        {
            ShowHint("没有加载过走向图数据");
            return;
        }

        sb.Clear();
        while (it.MoveNext())
        {
            var item = it.Current;
            var value = item.Value;
            string strConfig = value.ToJsonDataDic().ToSimpleJsonNode().ToString();

            ResourceManager.Instance.UpdateRouteData(PreRouteBuildInfoEditor + item.Key, strConfig, null, 
                resp =>
                {
                    if (HttpService.HasResponsError(resp))
                    {
                        sb.Append(resp.Error);
                        sb.Append('\n');
                        sb.Append(resp.WwwText);
                        sb.Append('\n');
                    }
                }
            );
        }
        string strResult = sb.ToString();
        if (string.IsNullOrEmpty(strResult))
        {
            ShowHint("保存到云端成功");
        }
        else
        {
            sb.Insert(0, "保存到云端失败 : \n");
            ShowHint(sb.ToString());
        }

    }

    public void RefreshEditedBuildingsColorSwitch(string lastRouteID, string curRouteID, string curBuildUID2Refresh = "")
    {
        if (lastRouteID != curRouteID)
        {
            var dicLast = dicRoutID2Buildinfos.TryGetReturnValue(lastRouteID);
            var dicCur = dicRoutID2Buildinfos.TryGetReturnValue(curRouteID);

            RefreshEditedBuildingsColorSwitch(dicLast, dicCur);
        }
    }

    public void RefreshEditedBuildingsColorSwitch(Dictionary<string, BuildInfo> lastDic, Dictionary<string, BuildInfo> curDic, string curBuildUID2Refresh = "")
    {
        if (null == curDic)
        {
            // 没有加载
            // 保持之前的选择
            return;
        }

        if (lastDic != curDic)
        {
            RevertEditedBuildingsColor(lastDic);;
        }
        if (curDic != GetCurBuildInfoDict())
        {
            Debug.LogError("不应该出现的逻辑, 在RefreshEditedBuildingsColorSwitch");
            return;
        }
        InnerRefreshCurEditedBuildingsColor(curBuildUID2Refresh);
    }


    void InnerRefreshCurEditedBuildingsColor(string buildUID2Refresh = "")
    {
        RefreshEditedBuildingsColor(GetCurBuildInfoDict(), GetIsShowingPhotoEditorEditedColor(), buildUID2Refresh);
    }

    public void RevertEditedBuildingsColor(Dictionary<string, BuildInfo> dic)
    {
        RefreshEditedBuildingsColor(dic, false);
    }

    public void RefreshEditedBuildingsColor(Dictionary<string, BuildInfo> curDic, bool isShowColor, string buildUID2Refresh = "")
    {
        if (null == curDic)
        {
            if (isShowColor)
            {
                EventManager.instance.DispatchEvent(null, UICONST.BIE_SHOW_ROUTE_EDITE_BUILDINGS_FAILED);                
                ShowHint("请先加载走向图数据");
                SetIsShowingPhotoEditorEditedColor(false);
            }
            return;
        }
        if (buildUID2Refresh == "")
        {
            var it = curDic.GetEnumerator();
            while (it.MoveNext())
            {
                var item = it.Current;
                var id = item.Key;
                var buildInfo = item.Value;
                RefreshSingleEditedBuildingColor(SceneManager.Instance.FindSceneNodeGO(id), buildInfo, isShowColor);
            }
        }
        else
        {
            if (isShowColor)
            {
                RefreshSingleEditedBuildingColor(SceneManager.Instance.FindSceneNodeGO(buildUID2Refresh), curDic.TryGetReturnValue(buildUID2Refresh), isShowColor);
            }
        }
    }

    public void RefreshSingleEditedBuildingColor(GameObject go, BuildInfo bdInfo, bool isShowing)
    {
        if (null == go)
        {
            return;
        }

        if (null == bdInfo)
        {
            ColorManager.GetIns().RevertColor(go);
            return;
        }

        if (isShowing)
        {
            if (bdInfo.picNameList.Count == 0)
            {
                ColorManager.GetIns().ChangeColor(go, ColorManager.Orange);
            }
            else
            {
                ColorManager.GetIns().ChangeColor(go, ColorManager.GrayGreen);
            }
        }
        else
        {
            ColorManager.GetIns().RevertColor(go);
        }
    }

    public void OnEvent(string eventName, object param)

    {
        switch (eventName)
        {
            case UICONST.BIE_GET_ROUTE_DATA:
                {
                    if (param != null)
                    {
                        string routeID = param.ToString();
                        RoteAreaData raData = MonoHelper.Instance.GetRouteDataById(PreRouteBuildInfoEditor + routeID);
                        // 原始本地数据
                        if (raData != null)
                        {
                            var lastRouteDicBuildID2Info = GetCurBuildInfoDict();
                            #region 获取走向图中建筑信息
                            if (raData.StrConfig != null)
                            {
                                if (!dicRoutID2Buildinfos.TryGetValue(routeID, out curLoadedRouteDicBuildID2Info))
                                {
                                    curLoadedRouteDicBuildID2Info = new Dictionary<string, BuildInfo>();
                                    dicRoutID2Buildinfos.Add(routeID, curLoadedRouteDicBuildID2Info);
                                    // 没有临时数据, 构造临时数据
                                    ParseBuildInfoData(raData.StrConfig, curLoadedRouteDicBuildID2Info);
                                }
                                else
                                {
                                    // 有临时数据, 使用临时数据
                                }
                            }
                            #endregion end 获取走向图中建筑信息

                            #region 获取走向图中图片
                            List<PicVO> list;
                            if (!dicRoutID2Pics.TryGetValue(routeID, out list))
                            {
                                if (raData.m_ab != null)
                                {
                                    var stringArray = raData.m_ab.GetAllAssetNames();
                                    for (int i = 0; i < stringArray.Length; i++)
                                    {
                                        dicRoutID2Pics.AddToList(routeID, new PicVO(stringArray[i], routeID));
                                    }
                                }
                            }
                            #endregion end 获取走向图中图片

                            // 刷新列表
                            EventManager.instance.DispatchEvent(null, UICONST.BIE_REFRESH_PHOTOLIST, routeID);
                            RefreshEditedBuildingsColorSwitch(lastRouteDicBuildID2Info, curLoadedRouteDicBuildID2Info);
                        }
                    }
                }
                break;
            case UICONST.BIE_SAVE_BUILDINFO:
                {
                    OnSaveBuildInfo(param as BuildInfo);
                }
                break;
            case UICONST.EventBtnClick:
                {
                    switch (param.ToString())
                    {
                        case UICONST.BTN_SAVE:
                            {
                                UpToServer();
                            }
                            break;
                        default:
                            break;
                    }
                }
                break;
            case UICONST.BIE_SHOW_ROUTE_EDITED_BUILDINGS_STATE_CHANGED:
                {
                    bool isShow = (bool)param;
                    SetIsShowingPhotoEditorEditedColor(isShow);
                }
                break;
            case UICONST.BIE_UPDATE_CURRENT_SHOWING_ROUTEID:
                {
                    string strCurShowingRouteID = (string)param;
                    _curShowingRouteID = (strCurShowingRouteID == null) ? string.Empty : strCurShowingRouteID ;
                }
                break;
            case UICONST.BIE_REQ_GET_LAST_SAVE_BUILDINFO:
                {
                    EventManager.instance.DispatchEvent(null, UICONST.BIE_RET_GET_LAST_SAVE_BUILDINFO, GetLastSaveBuildInfo());
                }
                break;
            case UICONST.BIE_REQ_GET_CUR_SAVE_BUILDINFO:
                {
                    EventManager.instance.DispatchEvent(null, UICONST.BIE_RET_GET_CUR_SAVE_BUILDINFO, GetCurSelectBuildInfo());
                }
                break;
            case UICONST.EventTreeItemClick:
                {
                    CurSelect = SceneNodeMono.GetSceneNodeFromGameObject(param as GameObject);
                }
                break;
            case UICONST.BIE_CLEAR_SLECTION:
                {
                    CurSelect = null;
                }
                break;
            default:
                break;
        }
    }

    public List<PicVO> GetPicVoByRouteID(string routeID)
    {
        return dicRoutID2Pics.TryGetReturnValue(routeID);
    }

    #endregion

    public void RequestRouteInfo(string strRouteID, Action reqFinishCallback = null)
    {
        MonoHelper.Instance.LoadRouteAb(PreRouteBuildInfoEditor + strRouteID, ()
        =>
        {
            if (reqFinishCallback != null)
            {
                reqFinishCallback();
            }
            EventManager.instance.DispatchEvent(null, UICONST.BIE_GET_ROUTE_DATA, strRouteID);
        });
    }

    // loadWorldCheck
    void ParseBuildInfoData(string picTxtStr, Dictionary<string, BuildInfo> dicID2BuildInfo)
    {
        dicID2BuildInfo.Clear();
        JsonData picJD = JsonMapper.ToObject(picTxtStr);

        foreach (var buildID in picJD.Keys)
        {
            JsonData buildInfoJD = picJD[buildID];
            BuildInfo bi = new BuildInfo().ReadJsonData(buildInfoJD) as BuildInfo;

            dicID2BuildInfo.AddRep(buildID, bi);
            //SetFlagColorByBuildInfo(build, bi);//TODO 着色系统
        }
    }
}

#region 数据结构

public class PicVO
{
    public string fileName;

    public string RouteID { get; set; }

    public PicVO(string fileName, string routeID)
    {
        this.fileName = fileName;
        RouteID = routeID;
    }
}

/// <summary>建筑信息 (建筑名,建筑类型,建筑绑定图片)</summary>
public class BuildInfo : IJsonData
{
    /// <summary>用于保存图片的引用, 导出JD时, 输出数据到picNameList</summary>
    //public List<PicVO> picList = new List<PicVO>();
    public List<string> picNameList = new List<string>();
    /// <summary>绑定图片的走向图ID</summary>
    public string picRouteID = "";
    public string buildName = "";
    public string buildType = "";
    public JsonData cameraPos;

    public bool isTemp = false;
    public JsonData ToJsonData()
    {
        JsonData jd = new JsonData();
        //保存时 直接赋值到picNameList
        //picNameList = picList.ConvertAll((tar) => { return SongeUtil.GetFileName(tar.fileName); });
        jd["picList"] = JsonUtils.ToJsonData(picNameList);
        jd["point"] = cameraPos;
        jd["picFolder"] = picRouteID;
        jd["buildName"] = buildName;
        jd["buildType"] = buildType;
        return jd;
    }

    public IJsonData ReadJsonData(JsonData jd)
    {
        buildType = jd.ReadString("buildType", "");
        buildName = jd.ReadString("buildName", "");
        picRouteID = jd.ReadString("picFolder");
        cameraPos = jd["point"];
        picNameList = jd["picList"].ToStringList();
        return this;
    }

    public BuildInfo GetClone()
    {
        BuildInfo newBdInfo = new BuildInfo();
        newBdInfo.ReadJsonData(ToJsonData());
        return newBdInfo;
    }
}
#endregion